Story4 연결 끊기

1 데이터 보내기를 완료했을 때 연결을 끊는다.

이번에 다룰 부분은 close()를 호출해 연결 해제를 하는 부분이다.

송신을 완료한 측에서 연결 끊기를 한다. 따라서 프로토콜 스택은 어느 쪽에서 먼저 끊기 단계에 들어갈 수 있도록 설계되었다.

일단 서버에서 연결 끊기를 한다고 가정해보자. 순서는 아래와 같다.

  1. 서버 애플리케이션에서 Socket 라이브러리의 close()를 호출하는 것이다.
  2. 프로토콜 스택은 TCP 헤드를 만드는데 여기의 FIN 비트를 1로 설정한다.
  3. 이제 IP 담당 부분에 의뢰하여 클라이언트에 패킷을 보낸다.
  4. 클라이언트에서는 FIN:1인 패킷을 받고 ACK 번호를 반송한다.
  5. 클라이언트 애플리케이션에서는 read()로 서버로부터 데이터를 기다리는 상태이므로 클라이언트의 프로토콜스택은 애플리케이션에게 데이터 수신 완료 했다는 사실을 알린다.
  6. 클라이언트 애플리케이션은 close()를 호출해 동작을 끝낸다.
  7. 이때 서버와 마찬가지로 FIN = 1을 설정한 TCP 헤더를 만들어 서버에게 보내고 ACK 번호가 돌아오면 서버와 대화를 끝낸다.

즉 아래 그림과 같다.

2 소켓 말소

연결이 끝나면 소켓을 사용해 서버와 대화할 수 없게 된다.

이때 소켓은 필요 없지만, 거기서 바로 말소하지 않고 오작동을 막기 위해 기다렸다가 말소한다.

여기서 다양한 오작동이 있을 수 있다.

가장 이해하기 쉬운 오작동은 ACK 번호가 돌아오지 않는 경우이다.

만약 ACK 번호가 돌아오지 않는다면, FIN을 다시 보낼 수 도 있는데, 상대편 소켓이 말소된 경우 제어 정보가 없으므로 포트번호를 알 수 없다.

만약 이런 상황에서 다른 애플리케이션이 소켓을 작성하면 새로운 소켓에 같은 포트 번호가 할당될 수 있다.

이런 경우 서버에서 다시 보낸 FIN이 그 소켓으로 가서 연결을 끊어버릴 수 있다.

이렇기 때문에 소켓을 바로 말소하지 않고 기다린다.